package com.itdct.mto.core.manager.base;

import com.itdct.mto.core.base.BaseManager;
import com.itdct.mto.core.bo.PartitionBo;
import com.itdct.mto.core.bo.TableBo;
import com.itdct.mto.core.context.Context;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

import lombok.extern.slf4j.Slf4j;

/**
 * @author Zhouwx
 * @date 2025/7/7 10:09:31
 * @version 1.0
 * @description
 */
@Slf4j
public abstract class BaseTableConvertManager extends BaseManager {

    public void covertTables(Context context) {
        log.info("开始将MySQL表转为OpenGauss {}模式", mtoConfig.getDatabaseMode());
        init(context);
        context.setConvertStartTime(System.currentTimeMillis());

        List<TableBo> tableBos = context.getTableBos();
        List<String> failTableNames = context.getFailTableNames();

        CountDownLatch countDownLatch = new CountDownLatch(tableBos.size());

        for (TableBo tableBo : tableBos) {
            String tableName = tableBo.getTableName();
            if (tableBo.getException() != null) {
                countDownLatch.countDown();
                continue;
            }
            threadPoolExecutor.submit(() -> {
                try {
                    String createTableSql = generateTableDdl(tableBo);
                    log.info("表：{} 对应的PG ddl 为：{}", tableName, createTableSql);

                    if (mtoConfig.isDropTable()) {
                        postgresJdbcTemplate.execute("DROP TABLE IF EXISTS " + tableName);
                    }
                    postgresJdbcTemplate.execute(createTableSql);
                    tableBo.setConvertSuccess(true);
                } catch (Exception e) {
                    log.error("表名：{}，执行失败", tableName);
                    log.error("", e);
                    tableBo.setConvertSuccess(false);
                    tableBo.setException(e);
                    failTableNames.add(tableName);
                } finally {
                    countDownLatch.countDown();
                }
            });
        }

        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            log.error("", e);
        }
        log.info("完成将MySQL表转为OpenGauss表，总共：{} 张表，失败 {} 张表", tableBos.size(), failTableNames.size());
        for (String failTable : failTableNames) {
            log.error("表名：{}，执行失败", failTable);
        }
        context.setConvertEndTime(System.currentTimeMillis());
    }

    protected String partitionBy(TableBo tableBo) {
        if (!tableBo.isPartitionTable()) {
            return "";
        }
        String partitionBy = tableBo.getPartitionBy();
        partitionBy = partitionBy.replace("`", "");
        StringBuilder stringBuilder = new StringBuilder("PARTITION BY " + partitionBy);
        stringBuilder.append("(");
        ArrayList<PartitionBo> partitionList = tableBo.getPartitionList();
        for (int i = 0; i < partitionList.size(); i++) {
            PartitionBo partitionBo = partitionList.get(i);
            String partitionName = partitionBo.getPartitionName();
            String partitionValue = partitionBo.getPartitionValue();
            partitionValue = partitionValue.replace("IN", "").trim();
            stringBuilder.append("PARTITION ")
                    .append(partitionName)
                    .append(" VALUES ")
                    .append(partitionValue);
            if (i != partitionList.size() - 1) {
                stringBuilder.append(",\n");
            }
        }

        stringBuilder.append(");\n");
        return stringBuilder.toString();
    }

    protected abstract String generateTableDdl(TableBo tableBo);
}
